﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using TwitterAPI;
using System.Windows;
using VsSpeakerCompanion;
using System.ComponentModel.Composition;
using System.Windows.Threading;
using VsSpeakerCompanion.UI;

namespace StartStopSessionWidget
{
    /// <summary>
    /// This is a non-visual widget that will send send twitter messages when a session is about to start
    /// and when a session just finished
    /// </summary>
    class Widget : IWidget
    {
        private const string StartSessionSettingKey = "StartSession";
        private const string EndSessionSettingKey = "EndSession";

        // we need access to context and some services
        private Context context;
        private TwitterService twitterService;
        private IUIService uiService;

        public Widget(Context context, TwitterService twitterService, IUIService uiService)
        {
            this.context = context;
            this.twitterService = twitterService;
            this.uiService = uiService;

            // listen to core events
            this.context.SessionStarted += new EventHandler(OnContextSessionStarted);
            this.context.SessionEnding += new EventHandler(OnContextSessionEnding);
        }

        private void OnContextSessionStarted(object sender, EventArgs e)
        {
            string sessionStartedValue = string.Concat(this.ConferenceHashcode, this.SessionHashcode);

            if (context.SharedSettings.Get<string>(StartSessionSettingKey) != sessionStartedValue)
            {
                if (this.uiService.ExecuteOperation(() => this.twitterService.UpdateStatus(
                    string.Format("#{0} Just starting to present {1}, follow it at #{2}",
                        this.ConferenceHashcode,
                        this.SessionName,
                        this.SessionHashcode
                        ))))
                {
                    context.SharedSettings.Update(StartSessionSettingKey, sessionStartedValue);
                }
            }
        }

        private void OnContextSessionEnding(object sender, EventArgs e)
        {
            string sessionEndedValue = string.Concat(this.ConferenceHashcode, this.SessionHashcode);

            if (context.SharedSettings.Get<string>(EndSessionSettingKey) != sessionEndedValue)
            {
                string message;
                double score;
                double total;

                // depending on if we can get a meaningful score
                // we will send one of two different message formats
                if (TryCalculateScore(out score, out total))
                {
                    // send message including calculated score
                    message = string.Format("#{0} #{1} Just finished {2} with a score of {3}/{4}",
                        this.ConferenceHashcode,
                        this.SessionHashcode,
                        this.SessionName,
                        score.ToString("0.00"),
                        total.ToString("0"));
                }
                else
                {
                    // send message without including the score
                     message = string.Format("#{0} #{1} Just finished {2}",
                        this.ConferenceHashcode,
                        this.SessionHashcode,
                        this.SessionName);
                }

                if (this.uiService.ExecuteOperation(() => this.twitterService.UpdateStatus(message)))
                {
                    context.SharedSettings.Update(EndSessionSettingKey, sessionEndedValue);
                }
            }
        }

        private bool TryCalculateScore(out double score, out double total)
        {
            score = total = 0;

            if (this.context.ContainsProperty("coolVotes") && this.context.ContainsProperty("notCoolVotes"))
            {
                try
                {
                    int coolVotes = this.context.GetProperty<int>("coolVotes");
                    int notCoolVotes = this.context.GetProperty<int>("notCoolVotes");

                    score = coolVotes;
                    total = coolVotes + notCoolVotes;

                    if (total > 0)
                    {
                        ChangeToBase5(ref score, ref total);
                        return true;
                    }
                }
                catch
                {
                    return false;
                }
            }

            return false;
        }

        private void ChangeToBase5(ref double score, ref double total)
        {
            score = score * 5 / total;
            total = 5;
        }

        private string ConferenceHashcode { get { return this.context.Settings.Get<string>("conferenceHashcode"); } }

        private string SessionName { get { return this.context.Settings.Get<string>("sessionName"); } }

        private string SessionHashcode { get { return this.context.Settings.Get<string>("sessionHashcode"); } }

        public UIElement VisualElement
        {
            get
            {
                // as this is a non-visual widget (it will only send twitter messages and show no UI)
                // we just return null here and this means we want to show no UI for our widget
                return null;
            }
        }

        public void Reset()
        {
            // no data to reset for this widget
        }
    }
}